import { ITEM_HEIGHT, MAX_ITEM_COUNT } from './config';
import { update, updatePaddingSet } from './render';
import { getData } from './utils';

const $state = {}; //在其上定义或修改属性的对象-列表。

/**
 * 列表改变（上滑、下拉）时，动态变化的属性
 * startIndex = Math.floor(scrollTop/itemHeight)；
 * endIndex = startIndex + (clientHeight/itemHeight) - 1；
 * paddingSet：paddingTop、paddingBottom
 * 这两个偏移量的作用就是来撑开容器元素的内容（缓冲区），
 * 从而起到缓冲的作用，使得滚动条保持平滑滚动，并使滚动条处于一个正确的位置
 */
const data = {
  dataSource: [], //初始化的列表数据
  curentData: [],//当前展示的列表数据
  startIndex: 0, //可视区域起始数据的索引值
  endIndex: 0, //当前视见区域结束数据的索引值
  paddingSet: {
    paddingTop: 0, //上滚动空白区域
    paddingBottom: 0,//下滚动空白区域
  }
}

export function reactive(list) {
  Object.defineProperties($state, {
    dataSource: {
      get() {
        return data.dataSource;
      },
      set(newValue) {
        data.dataSource = newValue;
        //更新currentData的数据
        setCurrentData();
      }
    },
    currentData: {
      get() {
        return data.currentData;
      },
      set(newValue) {
        data.currentData = newValue;
        //更新列表渲染的数据
        update($state.currentData, list);
      }
    },
    startIndex: {
      get() {
        return data.startIndex;
      },
      set(newValue) {
        if ($state.startIndex !== newValue) {
          data.startIndex = newValue;
          setCurrentData();
          //判断虚拟列表的数据是否已经滑到dataSource数组里的最后一条
          $state.endIndex >= $state.dataSource.length - 1
            &&
            setDataSource($state.dataSource.length + 1, $state.dataSource.length * 2);
          setPaddingSet();
        }

      }
    },
    endIndex: {
      get() {
        return setEndIndex();
      }
    },
    paddingSet: {
      get() {
        return data.paddingSet;
      },
      set(newValue) {
        data.paddingSet = newValue;
        updatePaddingSet($state.paddingSet, list);
      }
    }
  })

  return $state;
}

//设置endIndex的值
function setEndIndex() {
  const endIndex = $state.startIndex + MAX_ITEM_COUNT * 2; //虚拟列表设置为2屏
  //$state.dataSource[endIndex]不存在：证明列表后面无数据了，将endIndex的下标设置为总数据长度-1
  return $state.dataSource[endIndex] ? endIndex : $state.dataSource.length - 1;
}

//列表要加载的数据
export function setDataSource(init, count) {
  $state.dataSource = [
    ...$state.dataSource,
    ...getData(init, count)
  ]
  console.log('$state.dataSource', $state.dataSource)
  console.log('$state.dataSource不展开', [$state.dataSource, getData(init, count)])
}

//设置当前加载的数据
export function setCurrentData() {
  const startIndex = resetStartIndex();
  $state.currentData = $state.dataSource.slice(startIndex, $state.endIndex);
}

//设置上下滚动的空白区域-缓冲区
export function setPaddingSet() {
  const startIndex = resetStartIndex();
  $state.paddingSet = {
    paddingTop: startIndex * ITEM_HEIGHT,
    paddingBottom: ($state.dataSource.length - $state.endIndex) * ITEM_HEIGHT
  }
}

//更新startIndex的值
export function resetStartIndex() {
  return $state.startIndex <= MAX_ITEM_COUNT ? 0 : $state.startIndex - MAX_ITEM_COUNT;
}